//
//  ResourceTool.cpp
//  myhttpserver
//
//  Created by tgy on 2018/3/21.
//  Copyright © 2018年 tgy. All rights reserved.
//

#include "ResourceTool.hpp"
#include <dirent.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include "Utils.hpp"

#include <sstream>
#define READBUFSIZE 1024

Resource *ResourceTool::readFile(){
    
    Resource *resource = NULL;
    
    std::string path = basePath + relativePath;
    int fd = open(path.c_str(), O_RDONLY);
    std::cout << "文件描述符:"<<fd <<"  -----------------" << std::endl;
    if (fd < 0) {
        
        perror("open error");
        
        return resource;
    }
    
    char buf[READBUFSIZE];
    std::string tmpRead;
    while (true) {
        
        bzero(buf, READBUFSIZE);
        ssize_t read_num = read(fd, buf, READBUFSIZE);
        if (read_num < 0) {
            
            perror("read_num");
            
            return resource;

        }else if (read_num == 0 ){
            //读完了
            break;
        }else{
            
            tmpRead.append(buf, read_num);
        }
    }
    
    if (tmpRead.size() > 0) {
        
        char *data = new char[tmpRead.size()];
        strcpy(data, tmpRead.c_str());
        resource = new Resource(data, (int)tmpRead.size());
        
    }else{
        
        resource = new Resource();
    }
    
    resource->setLocalPath(path);

    close(fd);
    return resource;
}

Resource *ResourceTool::readDir(){
    
    Resource *resource = NULL;
    std::string path = basePath + relativePath;
    DIR *dir = opendir(path.c_str());
    //空文件夹
    if (dir == NULL) {
        
        return resource;
    }
    
    std::string sendData = "<!DOCTYPE html><html lang=\"zh\"><head><meta charset=\"UTF-8\"><title>Title</title></head><body>";
    std::ostringstream oss;
    do {
        
        struct dirent *dirt = readdir(dir);
        
        if (dirt == NULL) {
            
            break;
        }
        
        //文件名
        //    dirt->d_name;
        
        if (!Utils::canSendFileName(dirt->d_name)) {
            
            continue;
        }
        
        // //<a href="asd">asd</a><br>
        oss << "<a href=\"";
        if (relativePath != "/") {
            
            oss << relativePath;
        }
        oss<< "/" << dirt->d_name << "\">" << dirt->d_name << "</a><br>";
    } while (true);
    
    sendData.append(oss.str()).append("</body></html>");
    char *data = new char[sendData.size()];
    strcpy(data, sendData.c_str());
    resource = new Resource(data, (int)sendData.size());
    resource->setLocalPath(path);
    
    closedir(dir);
    return resource;
}


Resource *ResourceTool::readServer(){
    
    
    Resource *resource = NULL;
    
    struct stat st;
    std::string allPath = basePath + relativePath;
    int stat_resutl = stat(allPath.c_str(), &st);
    
    if (stat_resutl < 0) {  //没有这个文件或者目录
        
        return resource;
    }
    
    //    st.st_mode
    if (S_ISDIR(st.st_mode)) {  //目录
        
        //读目录
      resource =   readDir();
    }else if (S_ISREG(st.st_mode)){  //文件
        //读文件
      resource =  readFile();
    }
    
    return resource;
}

void ResourceTool::setBasePath(std::string basePath){
    
    this->basePath = basePath;
}

std::string ResourceTool::getBasePath(){
    
    return this->basePath;
}
void ResourceTool::setRelativePath(std::string relativePath){
    
    this->relativePath = relativePath;
}
std::string ResourceTool::getRelativePath(){
    
    return this->relativePath;
}
